# ~*~ coding: utf-8 ~*~
# auth: haochenxiao
import sys
import os
import time
import importlib
importlib.reload(sys)
import subprocess
import os
import logging
import sys
import datetime
from copy import deepcopy
import json
import shutil
import difflib
import redis
import requests
import subprocess

import paramiko
from django.db.models import Q
from django.shortcuts import render, redirect
from django.views.generic import TemplateView, View
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.contrib.auth import login, logout, authenticate
from django.urls import reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.http import FileResponse


from django.shortcuts import render_to_response,HttpResponse
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth import authenticate,login
from django.conf import settings
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.db import connection
from django import forms
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.models import User, Group, Permission
import configparser
from devops.auth import check
from devops.ansible_api import *
from devops.models import AutoReCovery,MonitorConfig
from users.models import Profile
from devops.ansible_api import *
from alert.models import LinkGroup


#定时任务调度
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job
scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), "default")
from devops.monitor_items import web_monitor,check_port,web_monitor_test,check_port_test
from confs.Configs import *
#时间对应关系
v_frequency = {0:1,1:5,2:15,3:30,4:60}
#v_frequency = {0:5,1:10,2:15,3:30,4:60}
#日志文件配置
from confs.Log import logger



def AddJob(func,frequency,name,args):
	# seconds minutes
	times = v_frequency[int(frequency)]
	scheduler.add_job(func, trigger='interval', id=name, minutes=times, args=args, coalesce=True,
					  replace_existing=True)

def ModifyJob(name,args):
	scheduler.modify_job(job_id=name,args=args)

class AutoRecoveryView(LoginRequiredMixin, TemplateView):
	template_name = 'autorecovery.html'

	def get_context_data(self, **kwargs):
		context = super(AutoRecoveryView, self).get_context_data(**kwargs)
		acy = AutoReCovery.objects.all()
		context['acy'] = acy
		return context


	def post(self,request):
		ret = {'status': 0}
		item = request.POST.get('item')
		alertime = request.POST.get('alertime')
		fixtime = request.POST.get('fixtime')
		action = request.POST.get('action')
		try:
			AutoReCovery.objects.create(item=item,alertime=alertime,fixtime=fixtime,action=action)
			ret['msg'] = '自动推送完成'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class AutoRecoveryEditView(LoginRequiredMixin, TemplateView):
	template_name = 'autorecovery_edit.html'

	def get(self, request):
		id = request.GET.get('id')
		acy = AutoReCovery.objects.get(id=id)
		return render_to_response('autorecovery_edit.html', locals())

	def post(self,request):
		ret = {'status': 0}
		item = request.POST.get('item')
		alertime = request.POST.get('alertime')
		fixtime = request.POST.get('fixtime')
		action = request.POST.get('action')

		try:
			acy = AutoReCovery.objects.get(item=item)
			acy.alertime = alertime
			acy.fixtime = fixtime
			acy.action = action
			acy.save()

			ret['msg'] = '自动推送完成'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return HttpResponseRedirect('/devops/autorecovery/')

class AutoRecoveryDeleteView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('autorecovery_id')
		try:
			arc = AutoReCovery.objects.get(id=id)
			arc.delete()
			ret['msg'] = '删除成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class AutoRecoveryStartView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('autorecovery_id')
		try:
			arc = AutoReCovery.objects.get(id=id)
			arc.status = 1
			arc.save()
			ret['msg'] = '启用成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class AutoRecoveryStopView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('autorecovery_id')
		try:
			arc = AutoReCovery.objects.get(id=id)
			arc.status = 0
			arc.save()
			ret['msg'] = '禁用成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)


class MonitorConfigView(LoginRequiredMixin, TemplateView):
	template_name = 'monitorconfig.html'

	def get_context_data(self, **kwargs):
		context = super(MonitorConfigView, self).get_context_data(**kwargs)
		mc = MonitorConfig.objects.all()
		ac_objects = AutoReCovery.objects.all()
		type_list = MonitorConfig.type_list
		frequency_list = MonitorConfig.frequency_list
		alert_list = LinkGroup.objects.all()
		alert_type_list = MonitorConfig.alert_type_list

		context['mc'] = mc
		context['ac_objects'] = ac_objects
		context['type_list'] = type_list
		context['frequency_list'] = frequency_list
		context['alert_list'] = alert_list
		context['alert_type_list'] = alert_type_list
		return context

	def post(self,request):
		ret = {'status': 0}
		name = request.POST.get('name')
		type = request.POST.get('type')
		url = request.POST.get('url','')
		frequency = request.POST.get('frequency','')
		remarks = request.POST.get('remarks')
		address = request.POST.get('address','')
		port = request.POST.get('port',0)
		#自愈
		ac_id = request.POST.get('ac_id', '')
		at_mc = AutoReCovery.objects.get(pk=ac_id)
		item = at_mc.item
		#告警
		linkgroup_id = request.POST.get('linkgroup_id', '')
		linkgroup = LinkGroup.objects.get(id=linkgroup_id)

		alert_type = request.POST.get('alert_type',1)


		#默认启用监控
		status = 1
		#v_frequency = {0:1,1:5,2:15,3:30,4:60}


		# 删除所有定时任务
		#scheduler.remove_all_jobs()
		#ret['status'] = 1
		#ret['msg'] = 'test'

		#站点监控
		if int(type) == 0:
			try:
				status_code = web_monitor_test(url,name,item)
				#print ('status_code is ',status_code)
				if status_code < 400:
					ret['status'] = 0
					# 添加定时任务
					AddJob(web_monitor, frequency, name, [url,name,item])
				else:
					ret['status'] = 1
					ret['msg'] = '返回状态码大于等于400,请查找原因'
			except Exception as e:
				logger.info(e)
				ret['status'] = 1
				ret['msg'] = str(e)
				return JsonResponse(ret)
		
		#端口监控
		if int(type) == 1:
			try:
				port_status = check_port_test(address,port,name,item)
				if port_status == 0:
					ret['status'] = 0
					AddJob(check_port, frequency, name, [address,port,name,item])
				else:
					ret['status'] = 1

			except Exception as e:
				logger.info(e)
				ret['status'] = 1
				ret['msg'] = str(e)
				return JsonResponse(ret)

		try:
			mcf = MonitorConfig.objects.create(name=name,type=type,url=url,frequency=frequency,remarks=remarks,status=status, \
										  address=address,port=port,alert_status=2,alert_type=alert_type)
			# 多对多添加
			mcf.mc.add(at_mc)
			mcf.ml.add(linkgroup)
			mcf.save()


			ret['msg'] = '自动推送完成'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)

		return JsonResponse(ret)


class MonitorConfigDeleteView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('monitorconfig_id')
		try:
			arc = MonitorConfig.objects.get(id=id)
			scheduler.remove_job(arc.name)
			arc.delete()
			ret['msg'] = '删除成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class MonitorConfigStopView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('monitorconfig_id')
		try:
			arc = MonitorConfig.objects.get(id=id)
			scheduler.pause_job(arc.name)
			arc.status = 0
			arc.save()
			ret['msg'] = '禁用成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class MonitorConfigStartView(LoginRequiredMixin, TemplateView):

	def post(self,request):
		ret = {'status': 0}
		id = request.POST.get('monitorconfig_id')
		try:
			arc = MonitorConfig.objects.get(id=id)
			scheduler.resume_job(arc.name)
			arc.status = 1
			arc.save()
			ret['msg'] = '启用成功'
		except Exception as e:
			logger.info(e)
			ret['status'] = 1
			ret['msg'] = str(e)
		return JsonResponse(ret)

class MonitorConfigEditView(LoginRequiredMixin, TemplateView):
	template_name = 'monitorconfig_edit.html'

	def get(self, request):
		id = request.GET.get('id')
		mcf = MonitorConfig.objects.get(id=id)
		acy_objs = AutoReCovery.objects.all()
		lg_objs = LinkGroup.objects.all()
		alert_type_list = MonitorConfig.alert_type_list
		return render_to_response('monitorconfig_edit.html', locals())

	def post(self,request):
		ret = {'status': 0}
		name = request.POST.get('mcname')
		ar_id = request.POST.getlist('ar_id')[0]
		linkgroup_id = request.POST.getlist('linkgroup_id')[0]
		alert_type = request.POST.get('alert_type')
		mcf = MonitorConfig.objects.get(name=name)
		mcf.alert_type = alert_type
		arc = AutoReCovery.objects.get(id=ar_id)
		mcf.mc.clear()
		mcf.mc.add(arc)
		lg_obj = LinkGroup.objects.get(id=linkgroup_id)
		mcf.ml.clear()
		mcf.ml.add(lg_obj)

		#端口定时任务修改
		if int(alert_type) == 1:
			address = mcf.address
			port = mcf.port
			item = arc.item
			args = [address, port, name, item]
			ModifyJob(name, args = args)
		#url定时任务修改
		if int(alert_type) == 0:
			item = arc.item
			args = [url,name,item]
			ModifyJob(name, args = args)


		mcf.save()

		ret['msg'] = '自动推送完成'

		return HttpResponseRedirect('/devops/monitor_config/')

# 注册定时任务并开始
register_events(scheduler)
scheduler.start()